home *** CD-ROM | disk | FTP | other *** search
/ SPACE 2 / SPACE - Library 2 - Volume 1.iso / utility / 252 / gemsrc / text.mod < prev    next >
Encoding:
Modula Implementation  |  1988-02-13  |  9.3 KB  |  319 lines

  1. IMPLEMENTATION MODULE Text;
  2.  
  3.  
  4.    (********************************************************************)
  5.  
  6.    PROCEDURE Length ( VAR Source : (* IN *) ARRAY OF CHAR ) : CARDINAL;
  7.  
  8.    VAR Count : CARDINAL;
  9.  
  10.    BEGIN
  11.       Count := 0;
  12.  
  13.       (*--- Loop until found a null character or exceeded the ---*)
  14.       (*--- maximum physical length of the string.            ---*)
  15.  
  16.       WHILE (Count <= HIGH (Source)) AND (Source[Count] <> CHR (0)) DO
  17.          INC (Count);
  18.       END;
  19.       RETURN ( Count );
  20.    END Length;
  21.  
  22.    (********************************************************************)
  23.  
  24.    PROCEDURE Assign (
  25.       VAR Source      : (* IN  *) ARRAY OF CHAR;
  26.       VAR Destination : (* OUT *) ARRAY OF CHAR );
  27.  
  28.    VAR Index : CARDINAL;
  29.  
  30.    BEGIN
  31.       Index := 0;
  32.  
  33.       (*--- Copy the characters from Source to Destination ---*)
  34.       (*--- one at a time.                                 ---*)
  35.  
  36.       LOOP
  37.          IF Index = HIGH (Destination) THEN
  38.  
  39.            (*--- There is no more space left in Destination, so     ---*)
  40.            (*--- finish the destination by adding a null character. ---*)
  41.  
  42.            Destination[Index] := CHR (0);
  43.            EXIT;
  44.  
  45.          ELSIF Index > HIGH (Source) THEN
  46.  
  47.            (*--- We have copied all of the characters from Source ---*)
  48.            (*--- into Destination, so finish the destination by   ---*)
  49.            (*--- adding a null character.                         ---*)
  50.  
  51.            Destination[Index] := CHR (0);
  52.            EXIT;
  53.  
  54.          ELSIF Source[Index] = CHR (0) THEN
  55.  
  56.            (*--- We have encountered the logical end of the source. ---*)
  57.            (*--- so finish the destination by adding a null         ---*)
  58.            (*--- character.                                         ---*)
  59.  
  60.            Destination[Index] := CHR (0);
  61.            EXIT;
  62.  
  63.          ELSE
  64.  
  65.            (*--- Continue to copy a character from Source to ---*)
  66.            (*--- Destination.                                ---*)
  67.  
  68.            Destination[Index] := Source[Index];
  69.            INC (Index);
  70.          END;
  71.       END;
  72.    END Assign;
  73.  
  74.    (********************************************************************)
  75.  
  76.    PROCEDURE Compare (
  77.       VAR LeftString  : (* IN *) ARRAY OF CHAR;
  78.       VAR RightString : (* IN *) ARRAY OF CHAR ) : CompareResult;
  79.  
  80.    VAR
  81.       LeftLength  : CARDINAL;
  82.       RightLength : CARDINAL;
  83.       Index       : CARDINAL;
  84.  
  85.    BEGIN
  86.  
  87.       (*--- Get the lengths of both strings ---*)
  88.  
  89.       LeftLength  := Length ( LeftString );
  90.       RightLength := Length ( RightString );
  91.  
  92.       IF LeftLength = 0 THEN
  93.         IF RightLength = 0 THEN
  94.           RETURN (Equal);
  95.         ELSIF RightLength > 0 THEN
  96.           RETURN (LessThan);
  97.         END;
  98.  
  99.       ELSE
  100.  
  101.         (*-- Iterate through the characters of LeftString, comparing --*)
  102.         (*-- each character of LeftString with that of RightString.  --*)
  103.  
  104.         FOR Index := 0 TO LeftLength - 1 DO
  105.           IF Index >= RightLength THEN
  106.  
  107.              (*--- Up to this point, each character of LeftString    --*)
  108.              (*--- has matched that of RightString.  Since we have   --*)
  109.              (*--- now exhausted RightString (LeftString is longer), --*)
  110.              (*--- indicate that LeftString is greater than          --*)
  111.              (*--- RightString.                                      --*)
  112.  
  113.              RETURN ( GreaterThan );
  114.  
  115.           ELSIF LeftString[Index] < RightString[Index] THEN
  116.  
  117.              (*--- The character from LeftString is less than the ---*)
  118.              (*--- corresponding character from RightString.      ---*)
  119.  
  120.              RETURN ( LessThan );
  121.  
  122.           ELSIF LeftString[Index] > RightString[Index] THEN
  123.  
  124.              (*-- The character from LeftString is greater than the ---*)
  125.              (*-- corresponding character from RightString.         ---*)
  126.  
  127.              RETURN ( GreaterThan );
  128.           END;
  129.         END;
  130.       END;
  131.  
  132.       (*--- All of the characters from LeftString match that from ---*)
  133.       (*--- RightString, so see if LeftString is shorter.         ---*)
  134.  
  135.       IF LeftLength = RightLength THEN
  136.  
  137.          (*--- The lengths are equal, so the strings are equal. ---*)
  138.  
  139.          RETURN ( Equal );
  140.  
  141.       ELSE
  142.  
  143.          (*--- LeftString is shorter than RightString. ---*)
  144.  
  145.          RETURN ( LessThan );
  146.       END;
  147.    END Compare;
  148.  
  149.    (********************************************************************)
  150.  
  151.    PROCEDURE SliceChar (
  152.       VAR Source : (* IN  *) ARRAY OF CHAR;
  153.       Position   : (* IN  *) CARDINAL;
  154.       VAR Result : (* OUT *) CHAR ) : BOOLEAN;
  155.  
  156.    BEGIN
  157.       IF Position >= Length ( Source ) THEN
  158.  
  159.          (*--- The requested position exceeds the current length ---*)
  160.          (*--- of the string.                                    ---*)
  161.  
  162.          RETURN ( FALSE );
  163.       ELSE
  164.          Result := Source[Position];
  165.          RETURN ( TRUE );
  166.       END;
  167.    END SliceChar;
  168.  
  169.    (********************************************************************)
  170.  
  171.    PROCEDURE SliceString (
  172.       VAR Source : (* IN  *) ARRAY OF CHAR;
  173.       Start      : (* IN  *) CARDINAL;
  174.       Stop       : (* IN  *) CARDINAL;
  175.       VAR Result : (* OUT *) ARRAY OF CHAR ) : BOOLEAN;
  176.  
  177.    VAR
  178.       SourceIndex : CARDINAL;
  179.       ResultIndex : CARDINAL;
  180.  
  181.    BEGIN
  182.       IF Start > Stop THEN
  183.  
  184.          (*--- The Start index exceeds the Stop index. ---*)
  185.  
  186.          RETURN ( FALSE );
  187.  
  188.       ELSIF Stop >= Length ( Source ) THEN
  189.  
  190.          (*--- The Stop index is greater than the current length ---*)
  191.          (*--- of the string.                                    ---*)
  192.  
  193.          RETURN ( FALSE );
  194.  
  195.       ELSIF Stop - Start > HIGH (Result) THEN
  196.  
  197.          (*--- The slice result exceeds the storage available. ---*)
  198.  
  199.          RETURN ( FALSE );
  200.  
  201.       ELSE
  202.  
  203.          (*--- Copy the characters from the source string to ---*)
  204.          (*--- Result, starting at the position indicated by ---*)
  205.          (*--- Start.                                        ---*)
  206.  
  207.          ResultIndex := 0;
  208.          FOR SourceIndex := Start TO Stop DO
  209.             Result[ResultIndex] := Source[SourceIndex];
  210.             INC ( ResultIndex );
  211.          END;
  212.          IF ResultIndex <= HIGH (Result) THEN
  213.  
  214.             (*--- Result can contain more characters than was   ---*)
  215.             (*--- sliced out of the source string, so terminate ---*)
  216.             (*--- Result with a null character.                 ---*)
  217.  
  218.             Result[ResultIndex] := CHR (0);
  219.          END;
  220.          RETURN ( TRUE );
  221.       END;
  222.    END SliceString;
  223.  
  224.    (********************************************************************)
  225.  
  226.    PROCEDURE ConcatChar (
  227.       VAR Source : (* IN  *) ARRAY OF CHAR;
  228.       Character  : (* IN  *) CHAR;
  229.       VAR Result : (* OUT *) ARRAY OF CHAR ) : BOOLEAN;
  230.  
  231.    VAR CharString : ARRAY [0..0] OF CHAR;
  232.  
  233.    BEGIN
  234.  
  235.       (*--- Make the character into a single character string, ---*)
  236.       (*--- so we can save code by calling ConcatString.       ---*)
  237.  
  238.       CharString[0] := Character;
  239.       RETURN ( ConcatString ( Source, CharString, Result ) );
  240.    END ConcatChar;
  241.  
  242.  
  243.    (********************************************************************)
  244.  
  245.    PROCEDURE ConcatString (
  246.       VAR LeftString  : (* IN  *) ARRAY OF CHAR;
  247.       VAR RightString : (* IN  *) ARRAY OF CHAR;
  248.       VAR Result      : (* OUT *) ARRAY OF CHAR ) : BOOLEAN;
  249.  
  250.    VAR
  251.       LeftLength  : CARDINAL;
  252.       RightLength : CARDINAL;
  253.       SourceIndex : CARDINAL;
  254.       ResultIndex : CARDINAL;
  255.  
  256.    BEGIN
  257.  
  258.       (*--- Get the lengths of both strings. ---*)
  259.  
  260.       LeftLength  := Length ( LeftString );
  261.       RightLength := Length ( RightString );
  262.  
  263.       IF (LeftLength + RightLength) > (HIGH (Result) + 1) THEN
  264.  
  265.          (*--- The length of the resulting string would exceed ---*)
  266.          (*--- the length available in Result.                 ---*)
  267.  
  268.          RETURN ( FALSE );
  269.  
  270.       ELSE
  271.  
  272.          (*--- Copy the contents of LeftString into Result. ---*)
  273.  
  274.          Assign ( LeftString, Result );
  275.  
  276.          (*--- Copy each character of RightString into Result, ---*)
  277.          (*--- starting at the end.                            ---*)
  278.  
  279.          ResultIndex := LeftLength;
  280.          IF RightLength > 0 THEN
  281.             FOR SourceIndex := 0 TO RightLength - 1 DO
  282.                Result[ResultIndex] := RightString[SourceIndex];
  283.                INC ( ResultIndex );
  284.             END;
  285.          END;
  286.  
  287.          IF ResultIndex <= HIGH (Result) THEN
  288.  
  289.             (*--- Result can contain more characters than that ---*)
  290.             (*--- obtained from concatenating LeftString with  ---*)
  291.             (*--- RightString, so terminate Result with a null ---*)
  292.             (*--- character.                                   ---*)
  293.  
  294.             Result[ResultIndex] := CHR (0);
  295.          END;
  296.          RETURN ( TRUE );
  297.       END;
  298.    END ConcatString;
  299.  
  300.    (********************************************************************)
  301.  
  302.    PROCEDURE UpperCase ( VAR String : (* IN *) ARRAY OF CHAR );
  303.  
  304.    VAR
  305.       Index : CARDINAL;
  306.       Ch    : CHAR;
  307.  
  308.    BEGIN
  309.       FOR Index := 0 TO HIGH ( String ) DO
  310.          Ch := String[Index];
  311.          IF (Ch >= 'a') AND (Ch <= 'z') THEN
  312.             String[Index] := CHR ( ORD (Ch) - (ORD ('a') - ORD ('A')));
  313.          END;
  314.       END (* DO *);
  315.    END UpperCase;
  316.  
  317. END Text.
  318.  
  319.